﻿using System.Collections.Generic;
using System.ServiceModel;
using Metro.Kashikoi.Common.Entity;
using Metro.Kashikoi.Common.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF;
using Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;

namespace Metro.Kashikoi.ServiceContract.Storage
{
    /// <summary>
    /// This interface provides methods to manage the storage.
    /// </summary>
    [ServiceContractAttribute]
    [ExceptionShielding]
    public interface IStorageService
    {
        /// <summary>
        /// Creates the inventory.
        /// </summary>
        /// <param name="inventory">The inventory to be created.</param>
        /// <param name="stockAreaId">The stock area id.</param>
        /// <returns> The newly created inventory.</returns>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        BinInventory CreateInventory(BinInventory inventory,
            [RangeValidator(0, RangeBoundaryType.Exclusive, int.MaxValue, RangeBoundaryType.Exclusive)]
            int stockAreaId);

        /// <summary>
        /// Updates the inventory.
        /// </summary>
        /// <param name="inventory">The inventory to be updated.</param>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        void UpdateInventory(BinInventory inventory);

        /// <summary>
        /// Updates the inventories stock status.
        /// </summary>
        /// <param name="inventories">The inventories.</param>
        /// <param name="stockStatus">The stock status.</param>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        void UpdateInventoriesStockStatus(ICollection<BinInventory> inventories, StockStatus stockStatus);

        /// <summary>
        /// Updates the inventory stock status.
        /// </summary>
        /// <param name="SSID">The SSID.</param>
        /// <param name="stockStatus">The stock status.</param>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        void UpdateInventoryStockStatus(string SSID, StockStatus stockStatus);

        /// <summary>
        /// Deletes the inventory.
        /// </summary>
        /// <param name="inventoryId">The inventory id.</param>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        void DeleteInventory(
            [RangeValidator(0, RangeBoundaryType.Exclusive, int.MaxValue, RangeBoundaryType.Exclusive)]
            int inventoryId);

        /// <summary>
        /// Deletes the inventories of stock areas.
        /// </summary>
        /// <param name="stockAreaIdList">The stock area id list.</param>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        void DeleteInventoriesOfStockAreas(IEnumerable<int> stockAreaIdList);

        /// <summary>
        /// Deletes the inventories of items.
        /// </summary>
        /// <param name="itemIdList">The item id list.</param>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        void DeleteInventoriesOfItems(IEnumerable<int> itemIdList);

        /// <summary>
        /// Gets the inventories of the specific stock areaId.
        /// </summary>
        /// <param name="stockAreaId">The stock area id.</param>
        /// <returns>A list of inventory.</returns>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        IList<BinInventory> GetInventoriesOfStockArea(
            [RangeValidator(0, RangeBoundaryType.Exclusive, int.MaxValue, RangeBoundaryType.Exclusive)]
            int stockAreaId);

        /// <summary>
        /// Gets the inventories of the specific stock areaId.
        /// </summary>
        /// <param name="stockAreaIdList">The stock area id list.</param>
        /// <returns>A list of inventory.</returns>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        IList<BinInventory> GetInventoriesOfStockAreas(IEnumerable<int> stockAreaIdList);

        /// <summary>
        /// Gets the list of inventory to be restocked in the specific regions.
        /// </summary>
        /// <param name="stockAreaIdList">The stock area id list.</param>
        /// <returns>
        /// A list of inventory to be restocked.
        /// </returns>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        IList<BinInventory> GetRestockList(IEnumerable<int> stockAreaIdList);

        /// <summary>
        /// Gets the inventory by id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns>The inventory.</returns>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        BinInventory GetInventoryById(
            [RangeValidator(0, RangeBoundaryType.Exclusive, int.MaxValue, RangeBoundaryType.Exclusive)]
            int id);

        /// <summary>
        /// Gets the inventory by SSID.
        /// </summary>
        /// <param name="SSID">The SSID.</param>
        /// <returns> The inventory.</returns>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        BinInventory GetInventoryBySSID(
            [StringLengthValidator(1, 255)]
            string SSID);

        /// <summary>
        /// Gets the inventories by item.
        /// </summary>
        /// <param name="itemId">The item id.</param>
        /// <returns>A list of inventory which stock the item.</returns>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        IList<BinInventory> GetInventoriesByItem(
            [RangeValidator(0, RangeBoundaryType.Exclusive, int.MaxValue, RangeBoundaryType.Exclusive)]
            int itemId);

        /// <summary>
        /// Clones the inventory.
        /// </summary>
        /// <param name="inventoryId">The inventory id of the inventory to be cloned.</param>
        /// <returns>The newly created inventory.</returns>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        BinInventory CloneInventory(
            [RangeValidator(0, RangeBoundaryType.Exclusive, int.MaxValue, RangeBoundaryType.Exclusive)]
            int inventoryId);

        /// <summary>
        /// Clones the inventories of stock area.
        /// </summary>
        /// <param name="fromStockAreaId">The id of the source stock area.</param>
        /// <param name="toStockAreaId">The id of the destination stock area.</param>
        [OperationContract]
        [ApplyDataContractResolver]
        [FaultContract(typeof(ServiceFault))]
        [FaultContract(typeof(ValidationFault))]
        IList<BinInventory> CloneInventoriesOfStockArea(
            [RangeValidator(0, RangeBoundaryType.Exclusive, int.MaxValue, RangeBoundaryType.Exclusive)]
            int fromStockAreaId,
            [RangeValidator(0, RangeBoundaryType.Exclusive, int.MaxValue, RangeBoundaryType.Exclusive)]
            int toStockAreaId);
    }
}
